package design_pattern

import (
	"sync"
	"sync/atomic"
)

// 实现单例模式

// 这个对吗？https://www.liwenzhou.com/posts/Go/singleton_in_go/
// 显然错的,这是一个错误示例
type singleton struct {
	v int
}
var _singleton *singleton

func NewSingleton() *singleton {
	if _singleton ==nil{
	_singleton = &singleton{}
	}
	return _singleton
}


// 正确示例

// 激进加锁
var mu sync.Mutex

func GetInstance() *singleton {
	mu.Lock()
	defer mu.Unlock()
	if _singleton ==nil{
		_singleton =&singleton{}
	}
	return _singleton
}

// double check

func GetInstance2() *singleton {
	if _singleton ==nil{
		mu.Lock()
		defer mu.Unlock()
		if _singleton ==nil{
			_singleton =&singleton{}
		}
	}
	return _singleton
}
// 设置原子化标识
var initialized int32
func GetInstance3() *singleton {

	if atomic.LoadInt32(&initialized)==1{
		return _singleton
	}
	mu.Lock()
	defer mu.Unlock()
	if _singleton ==nil{
		_singleton =&singleton{}
	}
	return _singleton
}

// 习惯用法
var once sync.Once

func GetInstance5() *singleton {
	once.Do(func() {
		_singleton =&singleton{}
	})
	return _singleton
}
